#pragma once

namespace Pan
{

    /**
     * @brief 字符类
     */
    class Char
    {

    public:
        /**
         * @brief 获取字符的值
         * @return 字符的值
         */
        inline const wchar_t value() const noexcept { return this->ch; }

    public:
        /**
         * @brief 判断一个字符是否大写字母
         * @return 是返回true，否返回false。
         */
        inline bool is_upper() const noexcept { return this->ch >= L'A' && this->ch <= L'Z'; }

    public:
        /**
         * @brief 判断一个字符是否小写字母
         * @return 是返回true，否返回false。
         */
        inline bool is_lower() const noexcept { return this->ch >= L'a' && this->ch <= L'z'; }

    public:
        /**
         * @brief 判断一个字符是否字母
         * @return 是返回true，否返回false。
         */
        inline bool is_letter() const noexcept { return this->is_upper() || this->is_lower(); }

    public:
        /**
         * @brief 判断一个字符是否数字
         * @return 是返回true，否返回false。
         */
        inline bool is_number() const noexcept { return this->ch >= L'0' && this->ch <= L'9'; }

    public:
        /**
         * @brief 判断字符是否字符串结束符
         * @return 是返回true，否返回false。
         */
        inline bool is_null() const noexcept { return this->ch == L'\0'; }

    public:
        /**
         * @brief 将指定字符转换为大写字符
         */
        inline Char &to_upper() &noexcept
        {
            if (this->is_lower())
            {
                this->ch += static_cast<wchar_t>(L'A' - L'a');
            }
            return *this;
        }
        inline Char &&to_upper() &&noexcept { return static_cast<Char &&>(this->to_upper()); }

    public:
        /**
         * @brief 将指定字符转换为小写字符
         */
        inline Char &to_lower() &noexcept
        {
            if (this->is_upper())
            {
                this->ch += L'a' - L'A';
            }
            return *this;
        }
        inline Char &&to_lower() &&noexcept { return static_cast<Char &&>(this->to_lower()); }

    public:
        inline bool equals(wchar_t ch) const noexcept { return this->ch == ch; }
        inline bool equals_ignore_case(wchar_t ch) const noexcept
        {
            wchar_t ch2 = this->ch;
            if (ch >= L'A' && ch <= L'Z')
                ch += L'a' - L'A';
            if (ch2 >= L'A' && ch2 <= L'Z')
                ch2 += L'a' - L'A';
            return ch == ch2;
        }

    private:
        /**
         * @brief 一个字符变量的引用
         */
        wchar_t ch;

    public:
        inline Char(const wchar_t _ch = L'\0') noexcept : ch(_ch) {}

    public:
        inline bool operator==(const Char &_ch)
        {
            return this->ch == _ch.ch;
        }

        inline bool operator!=(const Char &_ch)
        {
            return this->ch != _ch.ch;
        }
    };

} // namespace Pan
